import type { IBaseModuleTemplate } from '../template'
import { StylesService } from '../../types/constants/styles'
import { IconService } from '../icons'
import { MergeHandler } from '../merge_handler'
import { createStandardStyleTag, removeStandardStyleTag } from '../style_injector'
import { GMStorage } from './storage/gm_storage'
import { ThemeVarService } from './style/theme_var/service'

/**
 * 【基础模块类】
 * 提供支持域名隔离的存储管理等基础功能
 */
export abstract class BaseModule extends GMStorage implements IBaseModuleTemplate {
  private readonly mergeHandler: MergeHandler = MergeHandler.getInstance()
  protected readonly iconService: IconService = IconService.getInstance()
  readonly themeVarService: ThemeVarService = ThemeVarService.getInstance()
  readonly stylesService: StylesService = StylesService.getInstance()
  abstract readonly name: string
  abstract readonly supportedPlatforms?: string[] | undefined
  config: Record<string, any> = {}
  abstract applyConfig(config: any): void
  /**
   * 初始化模块
   */
  init(): void {
    this.core()
    this.isInitialized = true
    this.printResourceStats({ prefix: '模块初始化完成，' })
  }

  async initWithSync(): Promise<void> {
    await this.core()
    this.isInitialized = true
    this.printResourceStats({ prefix: '模块初始化完成，' })
  }

  abstract core(): Promise<void> | void

  /**
   * 抽象方法 - 功能切换回调
   * @param _id 功能 ID
   * @param checked 是否选中
   * @param _first 是否为首次加载
   */
  onToggleCallback(_id: string, checked: boolean, _first?: boolean): void {
    checked ? this.init() : this.destroy()
  }

  /**
   * 加载配置（支持域名隔离）
   */
  protected loadConfig(): void {
    this.config = this.mergeHandler.deepMerge(
      this.config,
      this.storage.get(`config#${this.id}`, {}, { useDomainIsolation: true }),
    )
  }

  /**
   * 更新配置（支持域名隔离）
   */
  protected updateConfig(config: object = {}): void {
    this.loadConfig()

    if (!config)
      return

    this.config = this.mergeHandler.deepMerge(this.config, config)
    this.storage.set(`config#${this.id}`, this.config, { useDomainIsolation: true })
  }

  /**
   * 注册样式
   */
  protected registerStyle(styleId: string, style: string): void {
    if (document.getElementById(styleId))
      return

    createStandardStyleTag(styleId, style)
  }

  /**
   * 移除样式
   */
  protected unregisterStyle(styleId: string): void {
    removeStandardStyleTag(styleId)
  }
}
